package com.zhang.controller.admin;

import com.alibaba.excel.EasyExcel;
import com.zhang.entity.Customer;
import com.zhang.entity.Supplier;
import com.zhang.service.LogService;
import com.zhang.service.SupplierService;
import com.zhang.entity.Log;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 后台管理供应商Controller
 */
@RestController
@RequestMapping("/admin/supplier")
public class  SupplierAdminController {
	
	@Resource
	private SupplierService supplierService;
	
	@Resource
	private LogService logService;
	
	/**
	 * 分页查询供应商信息
	 * @param supplier
	 * @param page
	 * @param rows
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/list")
	@RequiresPermissions(value = { "供应商管理" })
	public Map<String,Object> list(Supplier supplier, @RequestParam(value="page",required=false)Integer page, @RequestParam(value="rows",required=false)Integer rows)throws Exception{
		List<Supplier> supplierList=supplierService.list(supplier, page, rows, Direction.ASC, "id");
		Long total=supplierService.getCount(supplier);
		Map<String, Object> resultMap = new HashMap<>();
		resultMap.put("rows", supplierList);
		resultMap.put("total", total);
		logService.save(new Log(Log.SEARCH_ACTION,"查询供应商信息")); // 写入日志
		return resultMap;
	}
	
	/**
	 * 下拉框模糊查询
	 * @param q
	 * @return
	 * @throws Exception
	 */
	@ResponseBody
	@RequestMapping("/comboList")
	@RequiresPermissions(value = {"进货入库","退货出库","进货单据查询","退货单据查询"},logical=Logical.OR)
	public List<Supplier> comboList(String q)throws Exception{
		if(q==null){
			q="";
		}
		return supplierService.findByName("%"+q+"%");
	}
	
	
	
	/**
	 * 添加或者修改供应商信息
	 * @param supplier
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/save")
	@RequiresPermissions(value = { "供应商管理" })
	public Map<String,Object> save(Supplier supplier)throws Exception{
		if(supplier.getId()!=null){ // 写入日志
			logService.save(new Log(Log.UPDATE_ACTION,"更新供应商信息"+supplier)); 
		}else{
			logService.save(new Log(Log.ADD_ACTION,"添加供应商信息"+supplier)); 
		}
		Map<String, Object> resultMap = new HashMap<>();
		supplierService.save(supplier);			
		resultMap.put("success", true);
		return resultMap;
	}
	
	
	/**
	 * 删除供应商信息
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/delete")
	@RequiresPermissions(value = { "供应商管理" })
	public Map<String,Object> delete(String ids)throws Exception{
		Map<String, Object> resultMap = new HashMap<>();
		String []idsStr=ids.split(",");
		for(int i=0;i<idsStr.length;i++){
			int id=Integer.parseInt(idsStr[i]);
			logService.save(new Log(Log.DELETE_ACTION,"删除供应商信息"+supplierService.findById(id)));  // 写入日志
			supplierService.delete(id);							
		}
		resultMap.put("success", true);
		return resultMap;
	}

	/*TODO：*/
	/**
	 * 将客户信息导出Excel
	 * @param response
	 * @throws IOException
	 */
	@GetMapping("/download")
	@RequiresPermissions(value = { "供应商管理" })
	public Map<String,Object> download(HttpServletResponse response) throws IOException {

		Map<String,Object> resultMap = new HashMap<>();
		// 设置响应的内容类型为Excel文件格式，这告诉浏览器返回的内容是一个Excel文件，
		// application/vnd.openxmlformats-officedocument.spreadsheetml.sheet 是Office Open XML格式的Excel文件对应的MIME类型
		response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");

		// 设置响应的字符编码为UTF-8，确保文件中的中文等字符能正确编码，避免乱码问题
		response.setCharacterEncoding("utf-8");

		// 对要作为下载文件名的中文部分进行编码处理，使用UTF-8编码格式，URLEncoder.encode方法将中文字符转换为URL编码格式
		// 例如把"测试666"转换为相应的URL编码形式，同时使用replaceAll("\\+", "%20")是为了将编码后出现的'+'号替换为'%20'，
		// 这符合HTTP规范中对于空格等特殊字符在文件名中的处理要求，防止因文件名编码问题导致下载出错
		String fileName = URLEncoder.encode("测试666", "UTF-8").replaceAll("\\+", "%20");

		// 设置响应头的Content-disposition字段，用于告诉浏览器以下载的方式处理响应内容，而不是在浏览器中直接展示
		// attachment表示附件形式下载，filename*=utf-8''是一种符合RFC 6266规范的方式来指定带有编码的文件名，
		// 后面跟上经过处理后的文件名（包含后缀.xlsx），这样浏览器就能正确识别下载文件的名称及编码格式
		response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + "实时测试" + ".xlsx");

		// 打印出employeeSerevice.selectEmployee()的返回结果，此处可能是用于调试目的，查看从数据库等数据源获取的数据情况，
		// 可以根据打印出的内容排查是否获取到了预期的数据，不过在实际生产环境中，可能需要使用更合适的日志框架来记录这些信息，而不只是简单打印到控制台
		System.out.println("employeeSerevice.selectEmployee():" + supplierService.findAll());

		// 使用EasyExcel框架来进行Excel文件的写入操作，将数据写入到response的输出流中，这样浏览器就能接收到生成好的Excel文件内容
		// 第一个参数response.getOutputStream()指定了输出的目标流，也就是将生成的Excel内容通过HTTP响应返回给客户端（浏览器）
		// 第二个参数Employee.class指定了Excel文件中每行数据对应的Java实体类，EasyExcel会根据这个实体类的定义来确定Excel的列结构、数据类型等信息
		// 第三个参数.sheet("模板")表示创建一个名为"模板"的工作表，然后通过doWrite方法将从employeeSerevice.selectEmployee()获取到的数据写入到这个工作表中，
		// 如果在这个写入过程中出现IOException等异常情况，当前方法会将异常抛给上层调用者，需要注意进行适当的异常处理来保障程序的稳定性（当前代码在这方面可以优化）
		try {
			EasyExcel.write(response.getOutputStream(), Customer.class).sheet("供应商信息表").doWrite(supplierService.findAll());
			logService.save(new Log(Log.EXPORT_ACTION,"导出供应商信息"));  // 写入日志
			resultMap.put("success", true);
			return resultMap;
		} catch (IOException e) {
			// 可以设置响应状态码为500表示服务器内部错误
			response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
			// 给前端返回一个简单的错误提示信息，也可以返回更详细的错误内容（比如将异常信息进行处理后返回）
			response.getWriter().print("文件下载出现内部错误，请稍后再试");
			resultMap.put("error:",e);
			return resultMap;
		}
	}
}
